﻿using CXW.Core.Services;
using System;
using System.Text;

namespace CXW.Core
{
    /// <summary>
    /// Class with static methods to show message boxes.
    /// All text displayed using the MessageService.
    /// </summary>
    public static class MessageService
    {
        static string productName = "Application Name";

        /// <summary>
        /// Gets/Sets the name of the product using CXW.Core.
        /// Is used by the string parser as replacement for ${ProductName}.
        /// </summary>
        public static string ProductName
        {
            get { return productName; }
            set { productName = value; }
        }

        /// <summary>
        /// Shows an exception error.
        /// </summary>
        public static void ShowException(Exception ex)
        {
            ShowException(ex, null);
        }

        /// <summary>
        /// Shows an exception.
        /// </summary>
        public static void ShowException(Exception ex, string message)
        {
            LoggingService.Error(message, ex);
            LoggingService.Warn("Stack trace of last exception log:\n" + Environment.StackTrace);
            ServiceManager.Instance.MessageService.ShowException(ex, message);
        }

        /// <summary>
        /// Shows an exception.
        /// </summary>
        public static void ShowHandledException(Exception ex, string message = null)
        {
            LoggingService.Error(message, ex);
            LoggingService.Warn("Stack trace of last exception log:\n" + Environment.StackTrace);
            message = GetMessage(message, ex);
            ServiceManager.Instance.MessageService.ShowError(message);
        }

        static string GetMessage(string message, Exception ex)
        {
            if (message == null)
            {
                return ex.Message;
            }
            return message + "\r\n\r\n" + ex.Message;
        }
        #region ShowError
        /// <summary>
        /// Shows an error using a message box.
        /// </summary>
        public static void ShowError(string message, string caption = null)
        {
            LoggingService.Error(message);
            ServiceManager.Instance.MessageService.ShowError(message, caption);
        }

        /// <summary>
        /// Shows an error using a message box.
        /// <paramref name="formatstring"/> is first passed through the
        /// </summary>
        public static void ShowErrorFormatted(string formatstring, params object[] formatitems)
        {
            ShowError(Format(formatstring, formatitems));
        }

        /// <summary>Shows an error using a message box.</summary>
        public static void ShowErrorFormatted(string caption, string formatstring, params object[] formatitems)
        {
            ShowError(Format(formatstring, formatitems), caption);
        }
        #endregion
        #region ShowWarning
        /// <summary> Shows a warning message. </summary>
        public static void ShowWarning(string message, string caption = null)
        {
            LoggingService.Warn(message);
            ServiceManager.Instance.MessageService.ShowWarning(message, caption);
        }

        /// <summary> Shows a warning message. </summary>
        public static void ShowWarningFormatted(string formatstring, params object[] formatitems)
        {
            ShowWarning(Format(formatstring, formatitems));
        }

        /// <summary> Shows a warning message. </summary>
        public static void ShowWarningFormatted(string caption, string formatstring, params object[] formatitems)
        {
            ShowWarning(Format(formatstring, formatitems), caption);
        }
        #endregion        
        #region ShowMessage
        public static void ShowMessage(string message, string caption = null)
        {
            LoggingService.Info(message);
            ServiceManager.Instance.MessageService.ShowMessage(message, caption);
        }
        public static void ShowMessageFormatted(string formatstring, params object[] formatitems)
        {
            ShowMessage(Format(formatstring, formatitems));
        }

        public static void ShowMessageFormatted(string caption, string formatstring, params object[] formatitems)
        {
            ShowMessage(Format(formatstring, formatitems), caption);
        }
        #endregion
        #region AskQuestion
        /// <summary>
        /// Asks the user a Yes/No question, using "Yes" as the default button.
        /// Returns <c>true</c> if yes was clicked, <c>false</c> if no was clicked.
        /// </summary>
        public static bool AskQuestion(string question, string caption = null)
        {
            return ServiceManager.Instance.MessageService.AskQuestion(question, caption);
        }
        /// <summary>
        /// Asks the user a Yes/No question, using "Yes" as the default button.
        /// Returns <c>true</c> if yes was clicked, <c>false</c> if no was clicked.
        /// </summary>
        public static bool AskQuestionFormatted(string formatstring, params object[] formatitems)
        {
            return AskQuestion(Format(formatstring, formatitems));
        }
        /// <summary>
        /// Asks the user a Yes/No question, using "Yes" as the default button.
        /// Returns <c>true</c> if yes was clicked, <c>false</c> if no was clicked.
        /// </summary>
        public static bool AskQuestionFormatted(string caption, string formatstring, params object[] formatitems)
        {
            return AskQuestion(Format(formatstring, formatitems), caption);
        }
        #endregion
        static string Format(string formatstring, object[] formatitems)
        {
            try
            {
                return String.Format(formatstring, formatitems);
            }
            catch (FormatException ex)
            {
                LoggingService.Warn(ex);

                StringBuilder b = new StringBuilder(formatstring);
                foreach (object formatitem in formatitems)
                {
                    b.Append("\nItem: ");
                    b.Append(formatitem);
                }
                return b.ToString();
            }
        }
    }
}
